from pyspades.server import grenade_packet, block_action
from pyspades.common import coordinates, Vertex3
from pyspades.world import Grenade
from pyspades.constants import *

def apply_script(protocol, connection, config):
    
    class OneHitConnection(connection):
          def on_hit(self, hit_amount, hit_player):
              value = connection.on_hit(self, hit_amount, hit_player)
              if value is not None:
                  return value
              if self.weapon == 0: #RIFLE
                  if self.team != hit_player.team:
                      self.instagib_grenade(hit_player.world_object.position.x, hit_player.world_object.position.y, hit_player.world_object.position.z, 0)
                      return 100
                  else:
                      return hit_amount
              else:
                  return 0

          def on_spawn(self, pos):
              if self.weapon > 0: #RIFLE
                  self.kill()
                  self.send_chat('**  **  Press PERIOD to switch guns!  **  **')
                  self.send_chat('**  **  Rifles Only!  **  **')
              return connection.on_spawn(self, pos)
              
          def instagib_grenade(self, x, y, z, fuse):
              if self.name is None:
                  return
              grenade_packet.value = fuse
              grenade_packet.player_id = self.player_id
              grenade_packet.position = (x, y, z)
              grenade_packet.velocity = (0.0, 0.0, 0.0)
              self.protocol.send_contained(grenade_packet)
              position = Vertex3(x, y, z)
              velocity = Vertex3(0.0, 0.0, 0.0)
              instagib = self.protocol.world.create_object(Grenade, fuse,
                  position, None,
                  velocity, self.grenade_exploded_ig)
              instagib.name = 'instagib'

          def grenade_exploded(self, grenade):
              if self.name is None:
                  return
              position = grenade.position
              x = position.x
              y = position.y
              z = position.z
              if x < 0 or x > 512 or y < 0 or y > 512 or z < 0 or z > 63:
                  return
              x = int(x)
              y = int(y)
              z = int(z-1)
              tele_location = x, y, z
              self.set_location(tele_location)
              if self.on_block_destroy(x, y, z, GRENADE_DESTROY) == False:
                  return
              map = self.protocol.map
              for nade_x in xrange(x - 1, x + 2):
                  for nade_y in xrange(y - 1, y + 2):
                      for nade_z in xrange(z - 1, z + 2):
                          map.remove_point(nade_x, nade_y, nade_z)
                          self.on_block_removed(nade_x, nade_y, nade_z)
              block_action.x = x
              block_action.y = y
              block_action.z = z
              block_action.value = GRENADE_DESTROY
              block_action.player_id = self.player_id
              self.protocol.send_contained(block_action, save = True)
              self.protocol.update_entities()

          def grenade_exploded_ig(self, grenade):
              if self.name is None:
                  return
              position = grenade.position
              x = position.x
              y = position.y
              z = position.z
              if x < 0 or x > 512 or y < 0 or y > 512 or z < 0 or z > 63:
                  return
              x = int(x)
              y = int(y)
              z = int(z)
              for player in self.team.other.get_players():
                  if not player.hp:
                      continue
                  damage = grenade.get_damage(player.world_object.position)
                  if damage == 0:
                      continue
                  returned = self.on_hit(damage, player)
                  if returned == False:
                      continue
                  elif returned is not None:
                      damage = returned
                  player.set_hp(player.hp - damage, self,
                      hit_indicator = position.get(), type = GRENADE_KILL)
              if self.on_block_destroy(x, y, z, GRENADE_DESTROY) == False:
                  return
              map = self.protocol.map
              for nade_x in xrange(x - 1, x + 2):
                  for nade_y in xrange(y - 1, y + 2):
                      for nade_z in xrange(z - 1, z + 2):
                          map.remove_point(nade_x, nade_y, nade_z)
                          self.on_block_removed(nade_x, nade_y, nade_z)
              block_action.x = x
              block_action.y = y
              block_action.z = z
              block_action.value = GRENADE_DESTROY
              block_action.player_id = self.player_id
              self.protocol.send_contained(block_action, save = True)
              self.protocol.update_entities()
    return protocol, OneHitConnection
    